package jp.co.nes.awssupport.compile.function;

import java.time.YearMonth;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.batch.model.SubmitJobResult;

import jp.co.nes.awssupport.business.bean.CommonContainerBean.ProcessingResult;
import jp.co.nes.awssupport.business.bean.CompileContainerBean;
import jp.co.nes.awssupport.business.bean.CompileInfoBean;
import jp.co.nes.awssupport.business.logic.BillingCsvReader;
import jp.co.nes.awssupport.common.base.AbstractRequestHandler;
import jp.co.nes.awssupport.common.base.CommonException;
import jp.co.nes.awssupport.common.utility.AppInfoUtil;
import jp.co.nes.awssupport.common.utility.AwsBatchAsyncHelper;
import jp.co.nes.awssupport.common.utility.BeanUtil;
import jp.co.nes.awssupport.common.utility.DateUtil;

/**
 * 日次集計結果出力起動です(Lambda)。
 */
public class DailyCompiledBillingStart
        extends AbstractRequestHandler<CompileInfoBean, CompileContainerBean<CompileInfoBean>> {

    /** ロガー */
    private static Logger logger = LoggerFactory.getLogger(DailyCompiledBillingStart.class);

    /**
     * デフォルトコンストラクタです。
     */
    public DailyCompiledBillingStart() {
    }

    /*
     * (非 Javadoc)
     * @see jp.co.nes.awssupport.common.base.AbstractRequestHandler#handleRequest(java.lang.Object)
     */
    @Override
    protected CompileContainerBean<CompileInfoBean> handleRequest(CompileInfoBean input) {
        String categoryCsv = "BillingCsv";
        String bucketName = AppInfoUtil.getValAndEmptyChk(categoryCsv, "BucketName");

        String category = "DailyCompiledBillingStart";
        String jobNamePrefix0 = AppInfoUtil.getValAndEmptyChk(category, "JobNamePrefix");
        String jobQueue0 = AppInfoUtil.getValAndEmptyChk(category, "JobQueue");
        String jobDefinition0 = AppInfoUtil.getValAndEmptyChk(category, "JobDefinition");
        String jobNamePrefix1 = AppInfoUtil.getValAndEmptyChk(category, 1, "JobNamePrefix");
        String jobQueue1 = AppInfoUtil.getValAndEmptyChk(category, 1, "JobQueue");
        String jobDefinition1 = AppInfoUtil.getValAndEmptyChk(category, 1, "JobDefinition");
        long thresholdSize = AppInfoUtil.getLongValAndEmptyMinChk(category, 1, "ThresholdSize", 0);

        if (logger.isDebugEnabled()) {
            logger.debug(categoryCsv + ",BucketName=" + bucketName);
            logger.debug(category + ",0,JobNamePrefix=" + jobNamePrefix0);
            logger.debug(category + ",0,JobQueue=" + jobQueue0);
            logger.debug(category + ",0,JobDefinition=" + jobDefinition0);
            logger.debug(category + ",1,JobNamePrefix=" + jobNamePrefix1);
            logger.debug(category + ",1,JobQueuH=" + jobQueue1);
            logger.debug(category + ",1,JobDefinition=" + jobDefinition1);
            logger.debug(category + ",1,ThresholdSize=" + thresholdSize);
        }

        String jobNamePrefix = jobNamePrefix0;
        String jobQueue = jobQueue0;
        String jobDefinition = jobDefinition0;

        String targetYearMonthValue = input.getTargetYearMonthValue();
        YearMonth targetYearMonth = DateUtil.toYearMonth(targetYearMonthValue);
        String linkedAccountId = input.getLinkedAccountId();
        long size = getSize(bucketName, targetYearMonth, linkedAccountId);
        logger.info("size=" + size + ",thresholdSize=" + thresholdSize);
        if (size >= thresholdSize) {
            jobNamePrefix = jobNamePrefix1;
            jobQueue = jobQueue1;
            jobDefinition = jobDefinition1;
        }

        // 日次集計結果出力を起動
        AwsBatchAsyncHelper helper = null;
        try {
            helper = createAwsBatchAsyncHelper();
            Future<SubmitJobResult> future = helper.submitJobAsync(jobNamePrefix, jobQueue, jobDefinition);
            SubmitJobResult submitJobResult = future.get();

            StringBuilder builder = new StringBuilder();
            builder.append("JobId=");
            builder.append(submitJobResult.getJobId());
            builder.append(",JobName=");
            builder.append(submitJobResult.getJobName());
            logger.info(builder.toString());
        } catch (InterruptedException | ExecutionException e) {
            throw new CommonException(e);
        } finally {
            if (helper != null) {
                helper.shutdown();
            }
        }

        // 返却内容の設定
        CompileInfoBean info = new CompileInfoBean();
        BeanUtil.copyProperties(info, input);
        CompileContainerBean<CompileInfoBean> output = new CompileContainerBean<>();
        output.setInfoBean(info);
        output.setProcessingResult(ProcessingResult.SUCCESS);
        return output;
    }

    /**
     * 請求CSVのサイズを返却します。
     *
     * @param bucketName バケット名
     * @param targetYearMonth 処理対象年月
     * @param linkedAccountId 連結アカウントID
     * @return 請求CSVのサイズ
     */
    protected long getSize(String bucketName, YearMonth targetYearMonth, String linkedAccountId) {
        return BillingCsvReader.getSize(bucketName, targetYearMonth, linkedAccountId);
    }

    /**
     * AwsBatchAsyncヘルパーを生成します。
     *
     * @return AwsBatchAsyncヘルパー
     */
    protected AwsBatchAsyncHelper createAwsBatchAsyncHelper() {
        return new AwsBatchAsyncHelper();
    }
}
